package com.cskaoyan.shopping.service.impl;

import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.dto.ProductDto;
import com.cskaoyan.shopping.constants.ShoppingRetCode;
import com.cskaoyan.shopping.converter.CartItemConverter;
import com.cskaoyan.shopping.dal.entitys.Item;
import com.cskaoyan.shopping.dal.persistence.ItemMapper;
import com.cskaoyan.shopping.dto.CartProductDto;
import com.cskaoyan.shopping.form.CartRequest;
import com.cskaoyan.shopping.form.CheckAllItemRequest;
import com.cskaoyan.shopping.service.ICartService;
import com.cskaoyan.shopping.service.impl.cache.CacheManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @Author lixinhang
 * @Time 2022/9/21 9:55
 */
@Service
public class ICartServiceImpl implements ICartService {
    @Autowired
    CacheManager cacheManager;
    @Autowired
    ItemMapper itemMapper;
    @Autowired
    CartItemConverter cartItemConverter;

    //获取某用户的购物车列表
    @Override
    public List<CartProductDto> getCartListById(Long userId) {
        //根据userId获取redis中的购物车
        String uid = String.valueOf(userId);
        Map map = cacheManager.checkMap(uid);

        if(map.isEmpty()){
            return new ArrayList<CartProductDto>();
        }

        Collection<CartProductDto> values = map.values();
        List<CartProductDto> cartProductDtos = new ArrayList<>(values);
        return cartProductDtos;
    }

    //添加商品至用户购物车中
    @Override
    public void addToCart(CartRequest request) {
        @NotNull Long userId = request.getUserId();
        @NotNull Long productId = request.getProductId();
        Integer productNum = request.getProductNum();
        String checked = request.getChecked();

        String uid = String.valueOf(userId);
        String pid = String.valueOf(productId);

        //根据productId查询商品详情
        Example example = new Example(Item.class);
        example.createCriteria().andEqualTo("id", productId).andEqualTo("status", 1);
        List<Item> items = itemMapper.selectByExample(example);
        if (items.size() == 0) {
            throw new BizException(ShoppingRetCode.PRODUCT_NOT_EXISTS.getCode(), ShoppingRetCode.PRODUCT_NOT_EXISTS.getMessage());
        }

        //将items[0]转换为CartProductDto
        CartProductDto cartProductDto = cartItemConverter.item2Dto(items.get(0));
        cartProductDto.setChecked(checked);
        cartProductDto.setProductNum((long)productNum);

        //取出redission中该用户的购物车
        Map map = cacheManager.checkMap(uid);
        //如果该用户的购物车map的长度0，说明是首次添加商品至购物车,需要为该用户在redis中开辟一个购物车,并把商品map添加到购物车中
        if (map.isEmpty()) {
            HashMap<String, CartProductDto> cartProductDtoMap = new HashMap<>();
            cartProductDtoMap.put(pid, cartProductDto);
            cacheManager.setMap(uid, cartProductDtoMap, 30);
        } else {
            //如果该用户购物车不为空，去查看购物车中是否存在该商品
            CartProductDto existedCartProductDto = (CartProductDto)map.get(pid);
            if(existedCartProductDto != null){
                //如果用户购物车中已经存在该商品，则将数量相加
                cartProductDto.setProductNum(productNum + existedCartProductDto.getProductNum());
            }
            map.put(pid,cartProductDto);
        }
    }

    //更新购物车中的商品的数量
    @Override
    public void updateCartNum(CartRequest request) {
        @NotNull Long userId = request.getUserId();
        @NotNull Long productId = request.getProductId();
        Integer productNum = request.getProductNum();
        String checked = request.getChecked();
        String uid = String.valueOf(userId);
        String pid = String.valueOf(productId);

        Map map = cacheManager.checkMap(uid);
        if(map.isEmpty()){
            throw new BizException(ShoppingRetCode.ACCESS_CART_DATA_FAIL.getCode(),ShoppingRetCode.ACCESS_CART_DATA_FAIL.getMessage());
        }
        CartProductDto cartProductDto = (CartProductDto) map.get(pid);
        if(cartProductDto == null){
            throw new BizException(ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getCode(),ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getMessage());
        }
        cartProductDto.setProductNum((long)productNum);
        cartProductDto.setChecked(checked);
        map.put(pid,cartProductDto);
    }

    //全选购物车中的商品
    @Override
    public void checkAllCartItem(CheckAllItemRequest request) {
        Map map = cacheManager.checkMap(String.valueOf(request.getUserId()));
        if (map.isEmpty()) {
            throw new BizException(ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getCode(),ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getMessage());
        }
        Set set = map.keySet();
        for (Object o : set) {
            CartProductDto cpd = (CartProductDto) map.get(o);
            cpd.setChecked(request.getChecked());
            map.put(o,cpd);
        }
//        Collection<CartProductDto> values = map.values();
//        for (CartProductDto value : values) {
//            value.setChecked(request.getChecked());
//        }
    }

    //删除该用户购物车中的商品
    public void deleteCartItem(Long uid, Long productId) {
        Map map = cacheManager.checkMap(String.valueOf(uid));
        if (map.isEmpty() || (map.get(String.valueOf(productId)) == null)) {
            throw new BizException(ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getCode(),ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getMessage());
        }
        map.remove(String.valueOf(productId));
    }

    //删除选中的购物车商品
    @Override
    public void deleteCheckedItem(Long userId) {
        Map map = cacheManager.checkMap(String.valueOf(userId));
        if (map.isEmpty()) {
            throw new BizException(ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getCode(),ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getMessage());
        }
        Collection<CartProductDto> values = map.values();
        for (CartProductDto value : values) {
            if("true".equals(value.getChecked())){
                map.remove(String.valueOf(value.getProductId()));
            }
        }
    }
}
